﻿using HardWareSDK;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using ZK.Common;
using ZK.HardWareSDK;
using ZK.InterfaceServer;

namespace ZK.HardWareBLL
{
    /// <summary>
    /// 远睿通读卡器
    /// 杨伙盘的卡号规则
    /// 
    /// </summary>
    public class YRTReaderBLL : BaseBLL
    {
        private YRTReaderSDK reader;
        private InventoryBuffer m_curInventoryBuffer = new InventoryBuffer();
        System.Timers.Timer timerInventory = new System.Timers.Timer(Convert.ToInt32(AppConfigHelper.GetAppSettings("YRTCardReaderTimer")));
        private ReaderSetting m_curSetting = new ReaderSetting();
        private bool IsOpen = false;
        public bool IsInit = false;

        /// <summary>
        /// 数据回传委托
        /// </summary>
        /// <param name="epc"></param>
        public delegate void GetDataCallbackDelegate(string epc);
        /// <summary>
        /// 读卡器数据回传函数
        /// </summary>
        public GetDataCallbackDelegate getDataCallbackEvent;

        public YRTReaderBLL()
        {
        }
        public YRTReaderBLL(Models.TerminalM t)
        {
            this.terminal = t;
            this.IsInit = true;
            DelegateHelper.YRTResetEvent += YRTResetEvent1;
            //初始化访问读写器实例
            reader = new YRTReaderSDK();
            //回调函数
            reader.AnalyCallback = AnalyData;

            ConnectServer();
            Open();

            timerInventory.Elapsed += timerInventoryEvent;
            timerInventory.Enabled = true;
            timerInventory.AutoReset = false;
        }
        /// <summary>
        /// 重启读卡器
        /// </summary>
        private void YRTResetEvent1()
        {
            timerInventory.Elapsed -= timerInventoryEvent;
            reader.SignOut();
            Thread.Sleep(500);
            ConnectServer();
            Open();
            timerInventory.Elapsed += timerInventoryEvent;
            timerInventory.Enabled = true;
            timerInventory.AutoReset = false;
        }

        private void timerInventoryEvent(object sender, ElapsedEventArgs e)
        {
            try
            {
                reader.InventoryReal(m_curSetting.btReadId, m_curInventoryBuffer.btRepeat);
            }
            catch (Exception ex)
            {
                Common.Log4.LogManage.WriteErr(ex.ToString());
            }
            timerInventory.Start();
        }

        public void Open()
        {
            try
            {
                if (!IsOpen)
                {
                    IsOpen = true;
                    m_curInventoryBuffer.ClearInventoryPar();
                    m_curInventoryBuffer.btRepeat = 1;
                    m_curInventoryBuffer.bLoopCustomizedSession = false;
                    m_curInventoryBuffer.lAntenna.Add(0x00);
                    m_curInventoryBuffer.bLoopInventory = true;
                    m_curInventoryBuffer.bLoopInventoryReal = true;
                    m_curInventoryBuffer.ClearInventoryRealResult();
                    byte btWorkAntenna = m_curInventoryBuffer.lAntenna[m_curInventoryBuffer.nIndexAntenna];
                    reader.SetWorkAntenna(m_curSetting.btReadId, btWorkAntenna);
                    m_curSetting.btWorkAntenna = btWorkAntenna;

                    timerInventory.Start();
                }

            }
            catch (System.Exception ex)
            {

                Common.Log4.LogManage.WriteErr(ex.ToString());
                Common.DelegateHelper.InfoMessageEvent?.Invoke(ex.Message);
            }
        }

        public void Close()
        {
            IsOpen = false;
        }

        private void ConnectServer()
        {
            try
            {
                Models.TerminalM hardWareM = terminal; //IConfig.GetSetCardReader;
               // TestConnect.CheckDeviceStatus(hardWareM);
                //处理Tcp连接读写器
                string strException = string.Empty;
                IPAddress ipAddress = IPAddress.Parse(hardWareM.ip);
                int nPort = Convert.ToInt32(hardWareM.port);
                int nRet = reader.ConnectServer(ipAddress, nPort, out strException);
                // int nRet = 0;
                if (nRet != 0)
                {
                    string strLog = "连接读写器失败，失败原因： " + strException;
                    // SetMess(strLog);
                    Common.Log4.LogManage.WriteErr(strLog);
                    Common.DelegateHelper.InfoMessageEvent?.Invoke(strLog);
                    // AutoControlTransportApiServer.AddHardWareLog(hardWareM.Name, 1, strLog);
                    return;
                }
                else
                {
                    //SetMess("连接成功");
                }
            }
            catch (System.Exception ex)
            {
                // SetMess(ex.Message);
                Common.Log4.LogManage.WriteErr(ex.ToString());
                Common.DelegateHelper.InfoMessageEvent?.Invoke(ex.Message);
            }
        }
        private static readonly object obj = new object();
        // public string cardNum = string.Empty;
        private void AnalyData(MessageTran msgTran)
        {
            // SetMess("AnalyData");

            lock (obj)
            {
                if (msgTran.AryData.Length != 1)
                {
                    int nLength = msgTran.AryData.Length;
                    int nEpcLength = nLength - 4;
                    string strEPC = CCommondMethod.ByteArrayToString(msgTran.AryData, 3, nEpcLength);
                    if (strEPC.Length >= 12)
                    {
                        strEPC = strEPC.Substring(0, 12);
                        string header = strEPC.Substring(0, 6);
                      
                            //cardNum = strEPC;
                            Common.Log4.LogManage.WriteErr("YRTReaderBLL get cardNum " + strEPC);
                            getDataCallbackEvent?.Invoke(strEPC);
                        
                       
                    }
                }
                else
                {
                    string strErrorCode = CCommondMethod.FormatErrorCode(msgTran.AryData[0]);
                    string strLog = "读卡器回调失败，失败原因： " + strErrorCode;
                    Common.Log4.LogManage.WriteErr(strLog);
                }
            }
        }


    }

    class InventoryBuffer
    {
        public byte btRepeat;
        public byte btSession;
        public byte btTarget;
        public List<byte> lAntenna;
        public bool bLoopInventory;
        public int nIndexAntenna;
        public int nCommond;
        public bool bLoopInventoryReal;
        public bool bLoopCustomizedSession;

        public int nTagCount;
        public int nDataCount; //执行一次命令所返回的标签记录条数
        public int nCommandDuration;
        public int nReadRate;
        public int nCurrentAnt;
        public List<int> lTotalRead;
        public DateTime dtStartInventory;
        public DateTime dtEndInventory;
        public int nMaxRSSI;
        public int nMinRSSI;
        public DataTable dtTagTable;
        public DataTable dtTagDetailTable;

        public InventoryBuffer()
        {
            btRepeat = 0x00;
            lAntenna = new List<byte>();
            bLoopInventory = false;
            nIndexAntenna = 0;
            nCommond = 0;
            bLoopInventoryReal = false;

            nTagCount = 0;
            nReadRate = 0;
            lTotalRead = new List<int>();
            dtStartInventory = DateTime.Now;
            dtEndInventory = DateTime.Now;
            nMaxRSSI = 0;
            nMinRSSI = 0;

            dtTagTable = new DataTable();
            dtTagTable.Columns.Add("COLPC", typeof(string));
            dtTagTable.Columns.Add("COLCRC", typeof(string));
            dtTagTable.Columns.Add("COLEPC", typeof(string));
            dtTagTable.Columns.Add("COLANT", typeof(string));
            dtTagTable.Columns.Add("COLRSSI", typeof(string));
            dtTagTable.Columns.Add("COLINVCNT", typeof(string));
            dtTagTable.Columns.Add("COLFREQ", typeof(string));
            dtTagTable.Columns.Add("COLANT1", typeof(string));
            dtTagTable.Columns.Add("COLANT2", typeof(string));
            dtTagTable.Columns.Add("COLANT3", typeof(string));
            dtTagTable.Columns.Add("COLANT4", typeof(string));

            dtTagDetailTable = new DataTable();
            dtTagDetailTable.Columns.Add("COLEPC", typeof(string));
            dtTagDetailTable.Columns.Add("COLRSSI", typeof(string));
            dtTagDetailTable.Columns.Add("COLANT", typeof(string));
            dtTagDetailTable.Columns.Add("COLFRE", typeof(string));
        }

        public void ClearInventoryPar()
        {
            btRepeat = 0x00;
            lAntenna.Clear();
            //bLoopInventory = false;
            nIndexAntenna = 0;
            nCommond = 0;
            bLoopInventoryReal = false;
        }

        public void ClearInventoryResult()
        {
            nTagCount = 0;
            nReadRate = 0;
            lTotalRead.Clear();
            dtStartInventory = DateTime.Now;
            dtEndInventory = DateTime.Now;
            nMaxRSSI = 0;
            nMinRSSI = 0;
            dtTagTable.Rows.Clear();
        }

        public void ClearInventoryRealResult()
        {
            nTagCount = 0;
            nReadRate = 0;
            lTotalRead.Clear();
            dtStartInventory = DateTime.Now;
            dtEndInventory = DateTime.Now;
            nMaxRSSI = 0;
            nMinRSSI = 0;
            dtTagTable.Rows.Clear();
            dtTagDetailTable.Clear();
        }
    }

    class ReaderSetting
    {
        public byte btReadId;
        public byte btMajor;
        public byte btMinor;
        public byte btIndexBaudrate;
        public byte btPlusMinus;
        public byte btTemperature;
        public byte btOutputPower;
        public byte btWorkAntenna;
        public byte btDrmMode;
        public byte btRegion;
        public byte btFrequencyStart;
        public byte btFrequencyEnd;
        public byte btBeeperMode;
        public byte btGpio1Value;
        public byte btGpio2Value;
        public byte btGpio3Value;
        public byte btGpio4Value;
        public byte btAntDetector;
        public byte btMonzaStatus;
        public string btReaderIdentifier;
        public byte btAntImpedance;
        public byte btImpedanceFrequency;

        public int nUserDefineStartFrequency;
        public byte btUserDefineFrequencyInterval;
        public byte btUserDefineChannelQuantity;
        public byte btLinkProfile;

        public ReaderSetting()
        {
            btReadId = 0xFF;
            btMajor = 0x00;
            btMinor = 0x00;
            btIndexBaudrate = 0x00;
            btPlusMinus = 0x00;
            btTemperature = 0x00;
            btOutputPower = 0x00;
            btWorkAntenna = 0x00;
            btDrmMode = 0x00;
            btRegion = 0x00;
            btFrequencyStart = 0x00;
            btFrequencyEnd = 0x00;
            btBeeperMode = 0x00;
            btGpio1Value = 0x00;
            btGpio2Value = 0x00;
            btGpio3Value = 0x00;
            btGpio4Value = 0x00;
            btAntDetector = 0x00;
        }
    }
}
